﻿using Newtonsoft.Json.Linq;
using NLogManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;

namespace WJ.DataSender.Service.Commen
{
    public class CommenMethod
    {
        /// <summary>
        /// 当前时间转换为UTC时间输出秒数
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static int ConvertDateTimeToUtcs(DateTime time)
        {

            double intResult = 0;

            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));

            intResult = (time - startTime).TotalSeconds;

            return (int)intResult;

        }

        /// <summary>
        /// 当前时间转换为UTC时间输出毫秒数
        /// </summary>
        /// <param name="time">时间</param>
        /// <returns></returns>
        public static long ConvertDateTimeToUtcms(DateTime time)
        {

            double intResult = 0;

            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));

            intResult = (time - startTime).TotalSeconds;

            return (int)intResult;

        }


        /// <summary>
        /// 通过ping命令判断设备是否在线
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool EquipmentIsOnline(string ip)
        {
            bool isOnline = false;
            Ping ping = new Ping();
            PingReply pingReply = ping.Send(ip,CacheValues.AppsettingConfig.PingTimeOut);
            if(pingReply.Status == IPStatus.Success)
            {
                isOnline = true;
            }
            else
            {
                isOnline = false;
            }
            LogHelper.Debug($"{ip}是否在线：{isOnline}");
            return isOnline;
        }



        /// <summary>
        /// 将json转化成加签使用的字符串
        /// </summary>
        /// <param name="json">序列化后的字符串</param>
        /// <param name="ignoreProps">要忽略的字段</param>
        /// <param name="kvList">定义字典容器</param>
        /// <returns></returns>
        public static string CreateSignStr(string json, List<string> ignoreProps, Dictionary<string, string> kvList)
        {
            json = json.Replace("\r\n", string.Empty);
            json = json.Replace("\n", string.Empty);
            JObject o = JObject.Parse(json);
            foreach (var x in o)
            {
                if (ignoreProps.Contains(x.Key) || x.Value is null) continue;

                else
                    kvList.Add(x.Key, x.Value.ToString());//这里x.Key则为键，x.Value为值。可以选择使用字典
            }
            string[] keys = kvList.Keys.ToArray();
            Array.Sort(keys, string.CompareOrdinal);
            StringBuilder stringBuilder = new StringBuilder();
            foreach (var item in keys)
            {
                stringBuilder.Append(item + "=" + kvList[item].Replace("\r\n", string.Empty).Replace("\n",string.Empty)+ "&");
            }
            var result = stringBuilder.ToString().Replace(" ", string.Empty).Replace("\"", string.Empty).TrimEnd('&');
            return result;
        }


        public static string GetMD5Hash(string str)
        {
            //就是比string往后一直加要好的优化容器
            StringBuilder sb = new StringBuilder();
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
            {
                //将输入字符串转换为字节数组并计算哈希。
                byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));

                //X为     十六进制 X都是大写 x都为小写
                //2为 每次都是两位数
                //假设有两个数10和26，正常情况十六进制显示0xA、0x1A，这样看起来不整齐，为了好看，可以指定"X2"，这样显示出来就是：0x0A、0x1A。 
                //遍历哈希数据的每个字节
                //并将每个字符串格式化为十六进制字符串。
                int length = data.Length;
                for (int i = 0; i < length; i++)
                    sb.Append(data[i].ToString("X2"));

            }
            return sb.ToString();
        }

        /// <summary>
        /// 万集平台生成签名
        /// </summary>
        /// <param name="json"></param>
        /// <param name="ignoreProps"></param>
        /// <param name="kvList"></param>
        /// <returns></returns>
        public static string GenerateSign(string json, List<string> ignoreProps, Dictionary<string, string> kvList)
        {
            var str = CreateSignStr(json, ignoreProps, kvList);
            LogHelper.Debug($"待加签的字符串内容：{str}");
            return GetMD5Hash(str);
        }
    }
}
